package sshconfig

import (
	"fmt"
	"os"
	"os/exec"
	"strings"

	"go.uber.org/zap"
)

// SSHConfigChecker SSH配置检查器
// 负责配置验证和状态检查功能
type SSHConfigChecker struct {
}

// NewSSHConfigChecker 创建SSH配置检查器
func NewSSHConfigChecker() *SSHConfigChecker {
	return &SSHConfigChecker{}
}

// ValidateConfig 验证SSH配置
// 示例值: 无参数
func (c *SSHConfigChecker) ValidateConfig() error {
	zap.L().Info("验证SSH配置")

	// 检查sshd配置语法
	cmd := exec.Command("sshd", "-t")
	if output, err := cmd.CombinedOutput(); err != nil {
		return fmt.Errorf("SSH配置语法错误: %s", string(output))
	}

	zap.L().Info("SSH配置验证通过")
	return nil
}

// IsRootLoginEnabled 检查root登录是否启用
// 示例值: 无参数
func (c *SSHConfigChecker) IsRootLoginEnabled() (bool, error) {
	zap.L().Info("检查root登录配置")

	// 检查配置文件是否存在
	configFile := "/etc/ssh/sshd_config"
	if _, err := os.Stat(configFile); os.IsNotExist(err) {
		zap.L().Info("SSH配置文件不存在，默认启用root登录")
		return true, nil
	}

	// 读取配置文件内容
	content, err := os.ReadFile(configFile)
	if err != nil {
		return false, fmt.Errorf("读取SSH配置文件失败: %v", err)
	}

	// 查找PermitRootLogin设置
	lines := strings.Split(string(content), "\n")
	for i := len(lines) - 1; i >= 0; i-- {
		line := strings.TrimSpace(lines[i])
		if strings.HasPrefix(line, "PermitRootLogin") && !strings.HasPrefix(line, "#") {
			// 找到有效的PermitRootLogin设置
			parts := strings.Fields(line)
			if len(parts) >= 2 {
				value := strings.ToLower(parts[1])
				if value == "yes" || value == "true" || value == "1" || 
				   value == "without-password" || value == "prohibit-password" {
					zap.L().Info("检测到root登录已启用")
					return true, nil
				} else if value == "no" || value == "false" || value == "0" {
					zap.L().Info("检测到root登录已禁用")
					return false, nil
				}
			}
		}
	}

	zap.L().Info("未找到PermitRootLogin设置，默认启用root登录")
	return true, nil
}

// IsKeyOnlyLoginEnabled 检查仅密钥登录是否启用
// 示例值: 无参数
func (c *SSHConfigChecker) IsKeyOnlyLoginEnabled() (bool, error) {
	zap.L().Info("检查仅密钥登录配置")

	// 检查配置文件是否存在
	configFile := "/etc/ssh/sshd_config"
	if _, err := os.Stat(configFile); os.IsNotExist(err) {
		zap.L().Info("SSH配置文件不存在，默认允许密码登录")
		return false, nil
	}

	// 读取配置文件内容
	content, err := os.ReadFile(configFile)
	if err != nil {
		return false, fmt.Errorf("读取SSH配置文件失败: %v", err)
	}

	// 查找PasswordAuthentication设置
	lines := strings.Split(string(content), "\n")
	for i := len(lines) - 1; i >= 0; i-- {
		line := strings.TrimSpace(lines[i])
		if strings.HasPrefix(line, "PasswordAuthentication") && !strings.HasPrefix(line, "#") {
			// 找到有效的PasswordAuthentication设置
			parts := strings.Fields(line)
			if len(parts) >= 2 {
				value := strings.ToLower(parts[1])
				if value == "no" || value == "false" || value == "0" {
					zap.L().Info("检测到仅密钥登录已启用（密码认证已禁用）")
					return true, nil
				} else if value == "yes" || value == "true" || value == "1" {
					zap.L().Info("检测到仅密钥登录已禁用（密码认证已启用）")
					return false, nil
				}
			}
		}
	}

	zap.L().Info("未找到PasswordAuthentication设置，默认允许密码登录")
	return false, nil
}

// CheckConfigFiles 检查所有配置文件状态
func (c *SSHConfigChecker) CheckConfigFiles() (map[string]string, error) {
	zap.L().Info("检查SSH配置文件状态")

	configFiles := []string{
		"/etc/ssh/sshd_config",
		"/etc/ssh/ssh_config",
		"/etc/pam.d/sshd",
		"/etc/default/ssh",
		"/etc/default/sshd",
	}

	result := make(map[string]string)
	for _, file := range configFiles {
		if info, err := os.Stat(file); err == nil {
			result[file] = fmt.Sprintf("存在, 大小: %d bytes", info.Size())
		} else if os.IsNotExist(err) {
			result[file] = "不存在"
		} else {
			result[file] = fmt.Sprintf("检查失败: %v", err)
		}
	}

	return result, nil
}